using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using microsoft_TODO.DTOs;
using microsoft_TODO.Models;
using microsoft_TODO.MongoCore;
using MongoDB.Bson;
using MongoDB.Driver;
using server.DTOs;

namespace microsoft_TODO.ServiceCore.Services {
  public class TaskService : ITaskService {
    ITaskRepository _taskRepository;
    IListRepository _listRepository;
    IMapper _mapper;

    public TaskService (
      IMapper mapper,
      ITaskRepository taskRepository,
      IListRepository listRepository) {
      _mapper = mapper;
      _taskRepository = taskRepository;
      _listRepository = listRepository;
    }

    public List<Task> GetTasksByListId (string lid) {
      // return _taskRepository.GetAllList(u => u.ListId == lid);
      return null;
    }

    public IEnumerable<Task> GetTasksToday (string uid) {
      var todays = new List<Task> ();
      var tasksList = _listRepository.GetAll ().Select (u => u.Tasks);
      foreach (var tasks in tasksList) {
        todays.AddRange (tasks.Where (u => u.Today && !u.IsDone));
      }
      return todays.OrderByDescending (u => u.CreationTime);
    }

    public Task AddNewTask (NewTaskDto dto) {
      var task = new Task { Todo = dto.Todo };
      _listRepository.Update (
        u => u.Id == dto.ListId,
        Builders<CheckList<Task>>.Update.Push (u => u.Tasks, task)
      );
      var newTask = _listRepository.GetAll ().FirstOrDefault (u => u.Id == dto.ListId).Tasks.FirstOrDefault (u => u.Todo == dto.Todo);
      return newTask;
    }

    public void MoveToAnotherList (MoveTaskDto dto) {
      var task = _mapper.Map<Task> (dto);
      _listRepository.Update (
        u => u.Id == dto.ListId,
        Builders<CheckList<Task>>.Update.Push (u => u.Tasks, task)
      );
    }

    public bool RemoveTask (string lid, int index) {
      return _listRepository.RemoveTaskViaIndexOfArray (lid, index);
    }

    public bool ClearTaskDeadline (string lid, int index) {
      return _listRepository.UpdateTaskViaIndexOfArray (lid, index, "deadline", BsonNull.Value);
    }

    public bool UpdateTask (PutTaskDto dto) {
      var listId = dto.ListId;
      var index = dto.Index;
      string field = string.Empty;
      BsonValue value = BsonNull.Value;

      if (!string.IsNullOrWhiteSpace (dto.Todo)) {
        field = "todo";
        value = BsonString.Create (dto.Todo);
      }
      if (dto.IsDone.HasValue) {
        field = "isDone";
        value = BsonBoolean.Create (dto.IsDone.Value);
      }
      if (dto.Today.HasValue) {
        field = "today";
        value = BsonBoolean.Create (dto.Today.Value);
      }
      if (dto.ReminderTime.HasValue) {
        field = "reminderTime";
        value = BsonDateTime.Create (dto.ReminderTime.Value);
      }
      if (dto.Deadline.HasValue) {
        field = "deadline";
        value = BsonDateTime.Create (dto.Deadline.Value);
      }
      if (!string.IsNullOrEmpty (dto.Notes)) {
        field = "notes";
        value = BsonString.Create (dto.Notes);
      }

      return _listRepository.UpdateTaskViaIndexOfArray (
        listId,
        index,
        field,
        value
      );
    }
  }
}